package com.baidu.mpks.util;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.*;

public class JacksonUtils {

    private static final Logger log = LoggerFactory.getLogger(JacksonUtils.class);
    private static final String DATE_PATTERN = "yyyy-MM-dd HH:mm:ss";
    private static JsonFactory JSON_FACTORY = new JsonFactory();
    private static ObjectMapper OBJECT_MAPPER = createObjectMapper();
    public static final String EMPTY_JSON = "{}";

    public JacksonUtils() {
    }

    private static ObjectMapper createObjectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.configure(SerializationFeature.INDENT_OUTPUT, false);
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        return objectMapper;
    }

    public static <T> String toJson(T value) {
        if (value == null) {
            return "{}";
        } else {
            StringWriter sw = new StringWriter();
            JsonGenerator gen = null;

            try {
                gen = JSON_FACTORY.createGenerator(sw);
                OBJECT_MAPPER.writeValue(gen, value);
                String var3 = sw.toString();
                return var3;
            } catch (IOException var13) {
                log.error("object to json exception!", var13);
            } finally {
                if (gen != null) {
                    try {
                        gen.close();
                    } catch (IOException var12) {
                        log.warn("Exception occurred when closing JSON generator!", var12);
                    }
                }

            }

            return "{}";
        }
    }

    public static JsonNode toJsonNode(String value) {
        if (value == null) {
            return null;
        } else {
            try {
                return OBJECT_MAPPER.readTree(value);
            } catch (IOException var2) {
                log.error("object to json exception!", var2);
                return null;
            }
        }
    }

    public static List<String> asList(JsonNode node, String key) {
        if (node == null) {
            return Arrays.asList("null");
        } else {
            List<String> list = new ArrayList();
            JsonNode obj = node.get(key);
            if (obj == null) {
                return Arrays.asList("null");
            } else if (obj.isArray()) {
                if (obj != null) {
                    obj.forEach((x) -> {
                        list.add(x.asText());
                    });
                }

                return list;
            } else {
                return Arrays.asList(obj.asText());
            }
        }
    }

    public static String getString(JsonNode node, String key) {
        if (node == null) {
            return "";
        } else {
            JsonNode obj = node.get(key);
            if (obj == null) {
                return "";
            } else if (obj.isArray()) {
                return obj != null && obj.size() > 0 ? obj.get(0).asText() : "";
            } else {
                return obj.asText();
            }
        }
    }

    public static String getStringV2(JsonNode jsonNode, String key) {
        try {
            JsonNode jsonNode1 = jsonNode.get(key);
            if (jsonNode1 == null) {
                return null;
            } else {
                return jsonNode1.isTextual() ? jsonNode1.asText() : OBJECT_MAPPER.writeValueAsString(jsonNode1);
            }
        } catch (Exception var3) {
            log.error("JsonNode get value  exception!", var3);
            return null;
        }
    }

    public static Object getObject(JsonNode node, String key) {
        if (node == null) {
            return null;
        } else {
            JsonNode obj = node.get(key);
            if (obj == null) {
                return null;
            } else if (obj.isArray()) {
                return obj != null && obj.size() > 0 ? obj.get(0) : null;
            } else {
                return obj;
            }
        }
    }

    public static JsonNode getNode(JsonNode node, String key) {
        if (node == null) {
            return null;
        } else {
            JsonNode obj = node.get(key);
            if (obj == null) {
                return null;
            } else if (obj.isArray()) {
                return obj != null && obj.size() > 0 ? obj.get(0) : null;
            } else {
                return obj;
            }
        }
    }

    public static JsonNode addNode(JsonNode node, String key, Object value) {
        Map<String, Object> map = new HashMap();
        map.put(key, value);
        return addNode(node, map);
    }

    public static JsonNode addNode(JsonNode node, Map<String, Object> map) {
        if (node != null && MapUtils.isNotEmpty(map)) {
            Map<String, Object> nodeMap = toMap(node);
            Iterator var3 = map.entrySet().iterator();

            while(var3.hasNext()) {
                Map.Entry<String, Object> entry = (Map.Entry)var3.next();
                nodeMap.put(entry.getKey(), entry.getValue());
            }

            try {
                return toJsonNode(OBJECT_MAPPER.writeValueAsString(nodeMap));
            } catch (JsonProcessingException var5) {
                log.info("convert json is error, e---->" + var5);
            }
        }

        return node;
    }

    public static JsonNode merge(JsonNode mainNode, JsonNode updateNode) {
        Iterator fieldNames = updateNode.fieldNames();

        while(true) {
            while(fieldNames.hasNext()) {
                String fieldName = (String)fieldNames.next();
                JsonNode jsonNode = mainNode.get(fieldName);
                if (jsonNode != null && jsonNode.isObject()) {
                    merge(jsonNode, updateNode.get(fieldName));
                } else if (mainNode instanceof ObjectNode) {
                    JsonNode value = updateNode.get(fieldName);
                    ((ObjectNode)mainNode).put(fieldName, value);
                }
            }

            return mainNode;
        }
    }

    public static Map<String, Object> toMap(JsonNode node) {
        return (Map)OBJECT_MAPPER.convertValue(node, new TypeReference<Map<String, Object>>() {
        });
    }

    public static <T> T getObjectFromJson(String in, TypeReference<T> type) {
        try {
            return OBJECT_MAPPER.readValue(in, type);
        } catch (Exception var3) {
            log.info("json convert object is error in---->{},e---->{}", in, var3);
            return null;
        }
    }
}
